﻿using Basic.OAModel.DB;
using Basic.OARemoteModel;
using Basic.OARemoteModel.FillInItem.Model;
using Basic.OARemoteModel.UserFill.Model;
using WeDonekRpc.Helper;
using WeDonekRpc.Helper.IdGenerator;
using WeDonekRpc.Model;
using WeDonekRpc.SqlSugar;

namespace Basic.OADAL.Repository
{
    internal class EmpFillInItemDAL : BasicDAL<DBEmpFillInItem, long>, IEmpFillInItemDAL
    {
        public EmpFillInItemDAL ( IRepository<DBEmpFillInItem> basicDAL ) : base(basicDAL, "fill.item")
        {
        }
        public UserFillData GetItem ( long id )
        {
            UserFillData data = this._BasicDAL.JoinGet<DBEmpDataFillIn, UserFillData>(( a, b ) => a.FillInId == b.Id && a.Id == id, ( a, b ) => new UserFillData
            {
                Id = b.Id,
                ItemId = a.Id,
                Title = b.Title,
                FillType = b.FillType,
                BeginDate = b.BeginDate,
                EndDate = b.EndDate,
                CreateEmpId = b.CreateEmpId,
                FillInTime = a.FillInTime,
                Status = a.Status,
                Show = b.Show,
                FillStatus = b.Status,
                RevokeTime = a.RevokeTime,
                TableId = b.TableId
            });
            if ( data == null )
            {
                throw new ErrorException("oa.fill.item.not.find");
            }
            return data;
        }
        public Result[] Query<Result> ( FillInItemQuery query, IBasicPage paging, out int count ) where Result : class
        {
            paging.InitOrderBy("Id", true);
            return this._BasicDAL.Query<Result>(query.ToWhere(), paging, out count);
        }
        public long[] Query ( FillInItemQuery query, IBasicPage paging, out int count )
        {
            paging.InitOrderBy("Id", true);
            return this._BasicDAL.Query(query.ToWhere(), a => a.EmpId, paging, out count);
        }
        public UserFillItem[] QueryFillItem ( UserFillItemQuery query, IBasicPage paging, out int count )
        {
            paging.InitOrderBy("PublicTime", true);
            return this._BasicDAL.JoinQuery<DBEmpDataFillIn, UserFillItem>(query.ToWhere(), ( a, b ) => new UserFillItem
            {
                Id = b.Id,
                ItemId = a.Id,
                Title = b.Title,
                FillType = b.FillType,
                BeginDate = b.BeginDate,
                EndDate = b.EndDate,
                CreateEmpId = b.CreateEmpId,
                FillInTime = a.FillInTime,
                Status = a.Status
            }, paging, out count);
        }

        public void Revoke ( DBEmpFillInItem item )
        {
            item.Status = EmpFillInStatus.已撤回;
            item.RevokeTime = DateTime.Now;
            item.FillInTime = null;
            if ( !this._BasicDAL.Update(item, new string[]
            {
                "Status",
                "FillInTime",
                "RevokeTime"
            }) )
            {
                throw new ErrorException("oa.fill.item.revoke.fail");
            }
        }
        public void Submit ( DBEmpFillInItem item )
        {
            item.Status = EmpFillInStatus.已填;
            item.RevokeTime = null;
            item.FillInTime = DateTime.Now;
            if ( !this._BasicDAL.Update(item, new string[]
            {
                "Status",
                "FillInTime",
                "RevokeTime"
            }) )
            {
                throw new ErrorException("oa.fill.item.revoke.fail");
            }
        }

        public void Sync ( long fillInId, FillInEmp[] adds )
        {
            if ( this._BasicDAL.IsExist(a => a.FillInId == fillInId) )
            {
                this._Sync(fillInId, adds);
            }
            else
            {
                this._Add(fillInId, adds);
            }
        }
        private void _Add ( long fillInId, FillInEmp[] adds )
        {
            DBEmpFillInItem[] items = adds.ConvertAll(a => new DBEmpFillInItem
            {
                CompanyId = a.CompanyId,
                DeptId = a.DeptId,
                Status = EmpFillInStatus.未填,
                EmpId = a.EmpId,
                FillInId = fillInId,
                EmpName = a.EmpName,
                EmpNo = a.EmpNo,
                Id = IdentityHelper.CreateId(),
                UnitId = a.UnitId
            });
            this._BasicDAL.Insert(items);
        }
        private void _Sync ( long fillInId, FillInEmp[] adds )
        {
            DBEmpFillInItem[] items = adds.ConvertAll(a => new DBEmpFillInItem
            {
                CompanyId = a.CompanyId,
                DeptId = a.DeptId,
                Status = EmpFillInStatus.未填,
                EmpId = a.EmpId,
                FillInId = fillInId,
                EmpName = a.EmpName,
                EmpNo = a.EmpNo,
                Id = IdentityHelper.CreateId(),
                UnitId = a.UnitId
            });
            ISqlQueue<DBEmpFillInItem> queue = this._BasicDAL.BeginQueue();
            queue.Delete(a => a.FillInId == fillInId);
            queue.Insert(items);
            _ = queue.Submit();
        }
    }
}
